﻿using System;
using System.Windows;
using System.Windows.Browser;

namespace AgFractal
{
    public class MouseWheelHelper
    {
        public event EventHandler<MouseWheelEventArgs> Moved;
        private static readonly Worker worker = new Worker();
        private bool isMouseOver;

        public MouseWheelHelper(FrameworkElement element)
        {
            worker.Moved += HandleMouseWheel;

            element.MouseEnter += (sender, e) => isMouseOver = true;
            element.MouseLeave += (sender, e) => isMouseOver = false;
            element.MouseMove += (sender, e) => isMouseOver = true;
        }

        private void HandleMouseWheel(object sender, MouseWheelEventArgs args)
        {
            if (isMouseOver)
                Moved(this, args);
        }

        private class Worker
        {
            internal event EventHandler<MouseWheelEventArgs> Moved;

            internal Worker()
            {
                if (!HtmlPage.IsEnabled) return;

                HtmlPage.Window.AttachEvent("DOMMouseScroll", HandleMouseWheel);
                HtmlPage.Window.AttachEvent("onmousewheel", HandleMouseWheel);
                HtmlPage.Document.AttachEvent("onmousewheel", HandleMouseWheel);
            }

            private void HandleMouseWheel(object sender, HtmlEventArgs args)
            {
                double delta = 0;

                ScriptObject eventObj = args.EventObject;

                if (eventObj.GetProperty("wheelDelta") != null)
                {
                    delta = ((double)eventObj.GetProperty("wheelDelta")) / 120;


                    if (HtmlPage.Window.GetProperty("opera") != null)
                        delta = -delta;
                }
                else if (eventObj.GetProperty("detail") != null)
                {
                    delta = -((double)eventObj.GetProperty("detail")) / 3;

                    if (HtmlPage.BrowserInformation.UserAgent.IndexOf("Macintosh") != -1)
                        delta = delta * 3;
                }

                if (delta != 0 && Moved != null)
                {
                    MouseWheelEventArgs wheelArgs = new MouseWheelEventArgs(delta);
                    Moved(this, wheelArgs);

                    if (wheelArgs.Handled)
                        args.PreventDefault();
                }
            }
        }
    }
}